package com.etooling.framework.utils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
 * 字符处理类
 */
public class StrHandle {

    public static String[] split(String value) {
        List<String> list = new ArrayList<String>();
        int ind = 0;
        value = value == null ? "" : value;
        String[] values = value.split("\\$_\\{");
        if (values != null) {
            for (String var : values) {
                if (ind != 0) {
                    int index = -1;
                    try {
                        index = var.indexOf("}");
                    } catch (Exception e) {
                    }
                    if (index != -1) {
                        list.add("$_{" + var.substring(0, index + 1));
                        var = var.substring(index + 1);
                    }
                    if (var != null && !"".equals(var.trim())) {
                        list.add(var);
                    }
                } else {
                    if (var != null && !"".equals(var.trim())) {
                        list.add(var);
                    }
                }
                ind++;
            }
        }
        if (list.size() > 0) {
            values = new String[list.size()];
            for (int i = 0; i < values.length; i++) {
                values[i] = list.get(i);
            }
            return values;
        }
        return null;
    }

    public static Map<String, Object> analysisParam(String defaultValue) {
        // 处理日期参数先：

        Map<String, Object> map = new HashMap<String, Object>();
        int start = defaultValue.indexOf("${") == -1 ? -1 : defaultValue
                .indexOf("${") + 2;
        int type = 0;
        String result = defaultValue;
        if (start != -1) {
            int end = defaultValue.indexOf("}", start);
            if (end != -1) {
                type = 1;
                result = defaultValue.substring(start, end);
            }
        }
        map.put("type", type);
        map.put("result", result);
        return map;
    }

    // 如果一句语句出现多个自定义变成的话，就循环匹配，直到找不到自定义的变量为止。
    public String handleDate(String dateStr, String versionCode,
                             String versionCodeDateFm) {
        if (dateStr == null) {
            return "";
        }
        String arrayStr[] = dateStr.split("\r\n");

        boolean b = dateStr.indexOf("\r\n") > -1;
        String returnString = "";
        for (int i = 0; i < arrayStr.length; i++) {
            String tmp = "";
            tmp = handleDate1(arrayStr[i], versionCode, versionCodeDateFm);
            tmp = handleDate2(arrayStr[i], versionCode, versionCodeDateFm);
            if (b) {
                returnString = returnString + tmp + " ";
            } else {
                returnString = returnString + tmp;
            }
        }
        return returnString;
    }

    public String handleDate(String dateStr, String versionCode,
                             String versionCodeDateFm, String addEnter) {
        if (dateStr == null) {
            return "";
        }
        String arrayStr[] = dateStr.split("\r\n");

        boolean b = dateStr.indexOf("\r\n") > -1;
        String returnString = "";
        for (int i = 0; i < arrayStr.length; i++) {
            String tmp = "";
            tmp = handleDate1(arrayStr[i], versionCode, versionCodeDateFm);
            tmp = handleDate2(arrayStr[i], versionCode, versionCodeDateFm);
            if (b) {
                returnString = returnString + tmp + addEnter;
            } else {
                returnString = returnString + tmp;
            }
        }
        return returnString;
    }

    public String handleDate1(String dateStr, String versionCode,
                              String versionCodeDateFm) {
        String returnString = dateStr;
        while (true) {
            // System.out.println("123");
            String tmp = returnString;
            returnString = handleDateByDex(returnString, versionCode,
                    versionCodeDateFm);
            if (tmp.equals(returnString)) {
                return returnString;
            }
        }
    }

    public String handleDate2(String dateStr, String versionCode,
                              String versionCodeDateFm) {
        String returnString = dateStr;
        while (true) {
            // System.out.println("123");
            String tmp = returnString;

            returnString = handleDateByDexNoOtherValue(returnString,
                    versionCode, versionCodeDateFm);
            if (tmp.equals(returnString)) {
                return returnString;
            }
        }

    }

    // 如果一句语句出现多个自定义变成的话，就循环匹配，直到找不到自定义的变量为止。
    public String handleDate(String dateStr) {
        String returnString = dateStr;
        while (true) {
            String tmp = returnString;
            returnString = handleDateByDex(returnString, "", "");
            returnString = handleDateByDexNoOtherValue(returnString, "", "");
            if (tmp.equals(returnString)) {
                return returnString;
            }
        }

    }

    /**
     * 利用正式表达式，根据自定义时间参数语法，将参数变成对应的日期。支持当前日期+/- N日 +/-N月
     *
     * @return
     */
    public String handleDateByDex(String dateStr, String versionCode,
                                  String versionCodeDateFm) {
        DateFm df = new DateFm();
        String body = dateStr;
        String returnStr = body;
        returnStr = returnStr.replace("&", "");
        returnStr = returnStr.replace("=", "");

        String p = "[\\s\\S]+(\\$_\\{([a-zA-Z\u0100-\uFFFF0-9_]+)(\\+|\\-)([0-9]+)([mdMD]),([a-zA-Z||\\-||:|| ]+)\\})[\\s\\S]+";
        // String p =
        // "[a-zA-Z\u0100-\uFFFF]+=(getDate\\(thisDate(\\+|\\-)([0-9]+)))";
        Pattern p0 = Pattern.compile(p);

        Matcher m0 = p0.matcher(returnStr);
        if (m0.find()) {// 要进行日期处理
            String repacle_ = m0.group(1);// 原字符串
            String startDateStr = m0.group(2);// 函数名
            String c_ = m0.group(3);// 操作符

            int days = Integer.parseInt(m0.group(4));// 操作天数
            String addType = m0.group(5).toLowerCase();// 操作的类型m为月 d为日
            String dateForMat = m0.group(6);// 格式化

            Date startDate = new Date();
            if ("version_code".equals(startDateStr)
                    || "versionCode".equals(startDateStr)) {
                try {
                    startDate = df.to_date(versionCode, versionCodeDateFm);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if ("d".equals(addType)) {// 处理日
                if (c_.equals("+")) {
                    Date returnDate;
                    try {
                        returnDate = df.add_Date(startDate, days);
                        body = body.replace(repacle_, df.to_char(returnDate,
                                dateForMat));
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                } else {
                    Date returnDate;
                    try {
                        returnDate = df.r_Date(startDate, days);
                        body = body.replace(repacle_, df.to_char(returnDate,
                                dateForMat));
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }

            if ("m".equals(addType)) {// 处理日
                if (c_.equals("+")) {
                    Date returnDate;
                    try {

                        body = body.replace(repacle_, df.addMonth(startDate,
                                days, dateForMat));
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                } else {
                    Date returnDate;
                    try {
                        // returnDate = df.r_Date(new Date(), days);
                        body = body.replace(repacle_, df.rMonth(startDate,
                                days, dateForMat));
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }

        }
        p = "[\\s\\S]+(\\$_\\{([a-zA-Z\u0100-\uFFFF0-9_]+),([a-zA-Z||\\-||:|| ]+)\\})[\\s\\S]+";
        p0 = Pattern.compile(p);
        m0 = p0.matcher(returnStr);
        if (m0.find()) {
            // 要进行日期处理
            String repacle_ = m0.group(1);// 原字符串
            String startDateStr = m0.group(2);
            String dateForMat = m0.group(3);// 格式化

            Date startDate = new Date();
            try {
                body = body.replace(repacle_, df
                        .to_char(new Date(), dateForMat));
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return body;
    }

    /**
     * 利用正式表达式，根据自定义时间参数语法，将参数变成对应的日期。支持当前日期+/- N日 +/-N月
     *
     * @param articleBody
     * @return
     */
    public String handleDateByDexNoOtherValue(String dateStr,
                                              String versionCode, String versionCodeDateFm) {
        DateFm df = new DateFm();
        String body = dateStr;
        String returnStr = body;
        returnStr = returnStr.replace("&", "");
        returnStr = returnStr.replace("=", "");

        String p = "(\\$_\\{([a-zA-Z\u0100-\uFFFF0-9_]+)(\\+|\\-)([0-9]+)([mdMD]),([a-zA-Z||\\-||:|| ]+)\\})";
        // String p =
        // "[a-zA-Z\u0100-\uFFFF]+=(getDate\\(thisDate(\\+|\\-)([0-9]+)))";
        Pattern p0 = Pattern.compile(p);

        Matcher m0 = p0.matcher(returnStr);
        if (m0.find()) {// 要进行日期处理
            String repacle_ = m0.group(1);// 原字符串
            String startDateStr = m0.group(2);// 函数名
            String c_ = m0.group(3);// 操作符

            int days = Integer.parseInt(m0.group(4));// 操作天数
            String addType = m0.group(5).toLowerCase();// 操作的类型m为月 d为日
            String dateForMat = m0.group(6);// 格式化

            Date startDate = new Date();
            if ("version_code".equals(startDateStr)
                    || "versionCode".equals(startDateStr)) {
                try {
                    startDate = df.to_date(versionCode, versionCodeDateFm);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if ("d".equals(addType)) {// 处理日
                if (c_.equals("+")) {
                    Date returnDate;
                    try {
                        returnDate = df.add_Date(startDate, days);
                        body = body.replace(repacle_, df.to_char(returnDate,
                                dateForMat));
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                } else {
                    Date returnDate;
                    try {
                        returnDate = df.r_Date(startDate, days);
                        body = body.replace(repacle_, df.to_char(returnDate,
                                dateForMat));
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }

            if ("m".equals(addType)) {// 处理日
                if (c_.equals("+")) {
                    Date returnDate;
                    try {

                        body = body.replace(repacle_, df.addMonth(startDate,
                                days, dateForMat));
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                } else {
                    Date returnDate;
                    try {
                        // returnDate = df.r_Date(new Date(), days);
                        body = body.replace(repacle_, df.rMonth(startDate,
                                days, dateForMat));
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }

        }
        p = "(\\$_\\{([a-zA-Z\u0100-\uFFFF0-9_]+),([a-zA-Z||\\-||:|| ]+)\\})";
        p0 = Pattern.compile(p);
        m0 = p0.matcher(returnStr);
        if (m0.find()) {
            // 要进行日期处理
            String repacle_ = m0.group(1);// 原字符串
            String startDateStr = m0.group(2);
            String dateForMat = m0.group(3);// 格式化

            Date startDate = new Date();
            try {
                if ("version_code".equals(startDateStr)
                        || "versionCode".equals(startDateStr)) {
                    try {
                        startDate = df.to_date(versionCode, versionCodeDateFm);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                body = body
                        .replace(repacle_, df.to_char(startDate, dateForMat));
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

        return body;
    }

    /**
     * 利用正式表达式，根据自定义时间参数语法，将参数变成对应的日期。支持当前日期+/- N日 +/-N月
     *
     * @param articleBody
     * @return
     */

    public static String replaceTable(String template) {
        StringBuilder source = new StringBuilder();
        source.append(template);
        String[] labels = {"P", "FONT", "COLGROUP", "COL", "TBODY"};
        String[] properties = {"width", "height", "class"};
        String[] styles = {"HEIGHT", "WIDTH", "BORDER-COLLAPSE",
                "BORDER-BOTTOM", "BORDER-LEFT", "BORDER-TOP", "BORDER-RIGHT"};
        source = replaceLabel(source, labels);
        source = replacePropertyString(source, properties);
        source = replaceStyleString(source, styles);
        source = replaceTableStart(source);
        return source.toString();
    }

    private static StringBuilder replaceTableStart(StringBuilder source) {
        String str = "<TABLE border=0 cellSpacing=1 cellPadding=5 width=100% style=\"background:#333;text-align:center;font-size:12px;font-family:Courier New\"";
        if (source.indexOf("<TABLE") > -1) {
            return source.replace(source.indexOf("<TABLE"), source.indexOf(">",
                    source.indexOf("<TABLE") + 5), str);
        } else {
            return source;
        }
    }

    private static StringBuilder replacePropertyString(StringBuilder source,
                                                       String[] properties) {
        for (String property : properties) {
            int index = -1;
            while ((index = source.indexOf(property)) != -1) {
                int end1 = source.indexOf(" ", index);
                int end2 = source.indexOf(">", index);
                end1 = end1 == -1 ? end2 : end1;
                int end = end1 > end2 ? end2 : end1;
                source = source.replace(index - 1, end, "");
            }
        }
        return source;
    }

    private static StringBuilder replaceStyleString(StringBuilder source,
                                                    String[] properties) {
        for (String property : properties) {
            int index = -1;
            while ((index = source.indexOf(property)) != -1) {
                int end1 = source.indexOf(";", index);
                int end2 = source.indexOf("\"", index);
                end1 = end1 == -1 ? end2 : end1;
                int end = end1 >= end2 ? end2 : end1 + 2;
                source = source.replace(index, end, "");
            }
        }
        return source;
    }

    private static StringBuilder replaceLabel(StringBuilder source,
                                              String[] labels) {
        for (String label : labels) {
            int index = -1;
            String start = "<" + label;
            String end = "</" + label + ">";
            while ((index = source.indexOf(start)) != -1) {
                source = source.replace(index, source.indexOf(">", source
                        .indexOf(start)) + 1, "");
                int endIndex = source.indexOf(end);
                if (endIndex != -1) {
                    source = source.replace(endIndex, endIndex + label.length()
                            + 3, "");
                }
            }
        }
        return source;
    }

    public static String getContent1(List<Object[]> datas) {
        StringBuilder value = new StringBuilder();
        String td = "<td style=\"background-color:#fff\">";
        for (Object[] results : datas) {
            value.append("<tr>");
            for (Object result : results) {
                value.append(td).append(result == null ? "" : result).append(
                        "</td>");
            }
            value.append("</tr>");
        }
        return value.toString();
    }

    /**
     * 判断是否为数字.
     * 非0开头,位数为9.
     * 3位小数
     */
    public static boolean isNum(String str) {
        boolean flag1 = false;
        boolean flag2 = false;

        str = str.replaceFirst("-", "");
        if (str != null && !"".equals(str.trim())) {
            if (str.indexOf(".") != -1) {
                String[] strs = str.split("\\.");
                if (strs.length == 2) {
                    flag1 = strs[0].matches("^[0-9]\\d{0,8}$");
                    flag2 = strs[1].matches("^[0-9]\\d{0,3}$");
                }
            } else {
                flag1 = str.matches("^[1-9]\\d{0,8}$|[0]");
                flag2 = true;
            }
        }
        return flag1 && flag2;
    }


    /**
     * 测试表达式。
     *
     * @param args
     */
    public static void main(String[] args) {
        StrHandle sh = new StrHandle();
        System.out.println(sh.handleDate("$_{sysdate,yyyyMMdd}"));
    }

}
